package cn.rkylin.oms.common.utils;

import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.commons.lang.SerializationUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;

import org.springframework.beans.BeanUtils;
import cn.rkylin.oms.common.dto.DBLog;
import cn.rkylin.oms.system.log.dao.ILogDao;
import cn.rkylin.oms.system.log.domain.LogRecord;

/**
 * 日志工具类 实现org.apache.commons.logging.Log接口,向RabbitMQ发送日志，如果出现异常，则记录成本地日志
 * 
 * @author liming
 */
@Component("logUtil")
public class LogUtil {

    private static final String SOURCE_TYPE = "oms";

    private static final Log logger = LogFactory.getLog(LogUtil.class);
    /**
     * 消息队列模版接口
     */
    @Autowired
    private AmqpTemplate amqpTemplate;

    public void error(Object o) {
        try {
            DBLog log = (DBLog) o;
            log.setSourceType(SOURCE_TYPE);
            log.setLogType("error");
            log.setOperTime(DateUtil.getCurrentDateStr());
            //getAmqpTemplate().convertAndSend(SerializationUtils.serialize(log));
        } catch (Exception ex) {
            logger.info(o, ex);
        }
    }

    public void error(Object o, Throwable throwable) {
        try {
            DBLog log = (DBLog) o;
            log.setSourceType(SOURCE_TYPE);
            log.setLogType("error");
            log.setOperTime(DateUtil.getCurrentDateStr());
            log.setThrowable(getStackTraceInfo(throwable));
            //getAmqpTemplate().convertAndSend(SerializationUtils.serialize(log));
        } catch (Exception ex) {
            logger.info(o, ex);
        }
    }

    public void info(Object o) {
        try {
            DBLog log = (DBLog) o;
            log.setSourceType(SOURCE_TYPE);
            log.setLogType("info");
            log.setOperTime(DateUtil.getCurrentDateStr());
            //getAmqpTemplate().convertAndSend(SerializationUtils.serialize(log));
        } catch (Exception ex) {
            logger.info(o, ex);
        }
    }

    public void info(Object o, Throwable throwable) {
        try {
            DBLog log = (DBLog) o;
            log.setSourceType(SOURCE_TYPE);
            log.setLogType("info");
            log.setOperTime(DateUtil.getCurrentDateStr());
            log.setThrowable(getStackTraceInfo(throwable));
            //getAmqpTemplate().convertAndSend(SerializationUtils.serialize(log));
        } catch (Exception ex) {
            logger.info(o, ex);
        }
    }

    public void trace(Object o,ILogDao logDao,String userName) {
        try {
            DBLog log = (DBLog) o;
            log.setSourceType(SOURCE_TYPE);
            log.setLogType("trace");
            log.setOperTime(DateUtil.getCurrentDateStr());
            log.setUser(userName);
            //getAmqpTemplate().convertAndSend(SerializationUtils.serialize(log));
            // 查询日志表
            LogRecord logRecord=new LogRecord();
            BeanUtils.copyProperties(log, logRecord);
            logRecord.setCreateTime(new Date());
            logDao.insert(logRecord);
        } catch (Exception ex) {
            logger.info(o, ex);
        }
    }

    /**
     * 获取堆栈跟踪信息
     */
    private String getStackTraceInfo(Throwable throwable) {
        Map<String, String> tempMap = new LinkedHashMap<String, String>();
        StackTraceElement[] stackTraceElements = throwable.getStackTrace();
        for (int i = 0; i < stackTraceElements.length; i++) {
            tempMap.put("at" + i, stackTraceElements[i].toString());
        }
        return JSON.toJSONString(tempMap);
    }

    public AmqpTemplate getAmqpTemplate() {
        // 防止错误的使用此类（new LogUtil();）
//        if (this.amqpTemplate == null) {
//            this.amqpTemplate = BeanUtils.getBean("amqpTemplate");
//        }
        return this.amqpTemplate;
    }

    public void setAmqpTemplate(AmqpTemplate amqpTemplate) {
        this.amqpTemplate = amqpTemplate;
    }
}
